package sk.velkavrana.app.ui.components;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.util.Map;

/**
 * @author mtymes
 * @since May 26, 2009 10:52:37 AM
 */
public class JTextLink extends JLabel {

    private Action action;

    private boolean visited = false;
    private boolean underlinedAllowed = false;

    private boolean mouseOver = false;

//    private Color textColor = new Color(0, 0, 255);
//    private Color textVisited = new Color(148, 0, 173);
    //    private Color textOver = new Color(255, 0, 0);
    private Color textColor = Color.GRAY;
    private Color textVisited = Color.GRAY;
    private Color textOver = Color.BLACK;

    private int size;

    /////////////////////////////////////////////////////////////
    // constructors


    public JTextLink(String text, Icon icon, int horizontalAlignment, Action action) {
        super(text, icon, horizontalAlignment);
        setAction(action);
        if (action instanceof AbstractAction) {
            setText((String) ((AbstractAction) action).getValue(Action.NAME));
        }
        init();
    }


    public JTextLink(String text, int horizontalAlignment, Action action) {
        super(text, horizontalAlignment);
        setAction(action);
        if (action instanceof AbstractAction) {
            setText((String) ((AbstractAction) action).getValue(Action.NAME));
        }
        init();
    }


    public JTextLink(String text, Action action) {
        super(text);
        setAction(action);
        init();
    }


    public JTextLink(Icon image, int horizontalAlignment, Action action) {
        super(image, horizontalAlignment);
        setAction(action);
        init();
    }


    public JTextLink(Icon image, Action action) {
        super(image);
        setAction(action);
        init();
    }


    public JTextLink(Action action) {
        setAction(action);
        init();
    }


    public JTextLink(String text, Icon icon, int horizontalAlignment) {
        super(text, icon, horizontalAlignment);
        init();
    }


    public JTextLink(String text, int horizontalAlignment) {
        super(text, horizontalAlignment);
        init();
    }


    public JTextLink(String text) {
        super(text);
        init();
    }


    public JTextLink(Icon image, int horizontalAlignment) {
        super(image, horizontalAlignment);
        init();
    }


    public JTextLink(Icon image) {
        super(image);
        init();
    }


    public JTextLink() {
        init();
    }

    /////////////////////////////////////////////////////////////
    // initialization


    private void init() {
        setCursor(new Cursor(Cursor.HAND_CURSOR));

        // todo: maybe this part should be somewhere else
        Font font = getFont();
        size = font.getSize() - 1;
        recalculateFont();

        addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (action != null) {
                    action.actionPerformed(new ActionEvent(this, 0, "TextLink"));
                }
                JTextLink.this.setVisited(true);
            }


            public void mouseEntered(MouseEvent e) {
                mouseOver = true;

                recalculateFont();

                repaint();
            }


            public void mouseExited(MouseEvent e) {
                mouseOver = false;

                recalculateFont();

                repaint();
            }
        });
    }

    /////////////////////////////////////////////////////////////
    // methods


    public Action getAction() {
        return action;
    }


    public void setAction(Action action) {
        Action oldAction = getAction();
        if (action == null || !action.equals(oldAction)) {
            this.action = action;
            if (action instanceof AbstractAction) {
                setText((String) action.getValue(Action.NAME));
            }
        }
    }


    public boolean isVisited() {
        return visited;
    }


    public void setVisited(boolean visited) {
        boolean oldVisited = isVisited();

        this.visited = visited;

        if (visited != oldVisited) {
            repaint();
        }
    }


    private void recalculateFont() {
        Font font = getFont();

        boolean underline = false;

        if (mouseOver || underlinedAllowed) {
            underline = true;
        }

        Map attributes = font.getAttributes();

        attributes.put(TextAttribute.UNDERLINE, underline ? TextAttribute.UNDERLINE_ON : TextAttribute.UNDERLINE);
//        attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
        attributes.put(TextAttribute.SIZE, (float) size);
//        recalculateFont(font.deriveFont(font.getStyle() ^ Font.ITALIC));
//        recalculateFont(font.deriveFont(font.getStyle() | Font.ITALIC));

        setFont(font.deriveFont(attributes));
    }


    public boolean isUnderlinedAllowed() {
        return underlinedAllowed;
    }


    public void setUnderlinedAllowed(boolean underlinedAllowed) {
        boolean oldUnderlined = isUnderlinedAllowed();

        this.underlinedAllowed = underlinedAllowed;

        if (underlinedAllowed != oldUnderlined) {
            recalculateFont();
        }
    }

    /////////////////////////////////////////////////////////////
    // color processing


    public Color getTextColor() {
        return textColor;
    }


    public void setTextColor(Color textColor) {
        if (textColor != null && !textColor.equals(this.textColor)) {
            this.textColor = textColor;
            repaint();
        }
    }


    public Color getTextVisited() {
        return textVisited;
    }


    public void setTextVisited(Color textVisited) {
        if (textVisited != null && !textVisited.equals(this.textVisited)) {
            this.textVisited = textVisited;
            repaint();
        }
    }


    public Color getTextOver() {
        return textOver;
    }


    public void setTextOver(Color textOver) {
        if (textOver != null && !textOver.equals(this.textOver)) {
            this.textOver = textOver;
            repaint();
        }
    }


    public Color getForeground() {
        if (mouseOver) {
            return textOver;
        } else if (!isVisited()) {
            return textColor;
        } else {
            return textVisited;
        }
    }
}

